home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Toolbox / Live Scroll 1.0 / Sources / Windows.c < prev   
Encoding:
C/C++ Source or Header  |  1996-05-13  |  17.7 KB  |  788 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Windows.c
  3.  
  4.     Contains:    Handle application's windows
  5.  
  6.     Written by:    Chris White, Developer Technical Support
  7.     
  8.     Copyright:    © 1996 by Apple Computer, Inc., all rights reserved.
  9.     
  10.     Change History (most recent first):
  11.     
  12.             03/29/96            CW        First release
  13.  
  14. */
  15.  
  16.  
  17. #pragma segment Core
  18.  
  19.  
  20.  
  21. // System Includes
  22.  
  23. #ifndef __TYPES__
  24.     #include <Types.h>
  25. #endif
  26.  
  27. #ifndef __WINDOWS__
  28.     #include <Windows.h>
  29. #endif
  30.  
  31. #ifndef __DIALOGS__
  32.     #include <Dialogs.h>
  33. #endif
  34.  
  35. #ifndef __QUICKDRAW__
  36.     #include <Quickdraw.h>
  37. #endif
  38.  
  39. #ifndef __PICTUTILS__
  40.     #include <PictUtils.h>
  41. #endif
  42.  
  43. #ifndef __RESOURCES__
  44.     #include <Resources.h>
  45. #endif
  46.  
  47. #ifndef __FONTS__
  48.     #include <Fonts.h>
  49. #endif
  50.  
  51. #ifndef __TOOLUTILS__
  52.     #include <ToolUtils.h>
  53. #endif
  54.  
  55. #ifndef __ERRORS__
  56.     #include <Errors.h>
  57. #endif
  58.  
  59.  
  60.  
  61.  
  62. // Application Includes
  63.  
  64. #ifndef __BAREBONES__
  65.     #include "BareBones.h"
  66. #endif
  67.  
  68. #ifndef __PROTOTYPES__
  69.     #include "Prototypes.h"
  70. #endif
  71.  
  72.  
  73.  
  74.  
  75. // Static prototypes
  76. static OSErr        CreateDocumentWindow ( WindowRef* windowRef );
  77. static GWorldPtr    CreateOffscreen ( CTabHandle theCTabHndl, SInt16 theXsize, SInt16 theYsize,
  78.                                         SInt16 theBitDepth, GWorldFlags theFlags );
  79. static OSErr        DrawPictToOffscreen ( PicHandle thePictHndl, GWorldPtr theOffscreen );
  80. static OSErr        DrawOffscreenToWindow ( GWorldPtr theOffscreen, WindowPtr theWindow );
  81. static Rect            GetWindowVisibleRect ( WindowRef theWindow, SInt16 theSizeX, SInt16 theSizeY );
  82. static void            SaveSetMMUMode ( Boolean bIsSaveMode );
  83. static void            DrawClippedScrollBarLines ( WindowRef theWindow );
  84. static void            DrawClippedGrowIcon ( WindowRef theWindow );
  85. static void            HandleContentClick ( WindowRef theWindow, EventRecord* event );
  86. static OSErr        CreateWindowInfo ( WindowRef windowRef, Size infoSize );
  87. static pascal OSErr    SafeGetPictInfo ( PicHandle thePictHandle, PictInfo* thePictInfo,
  88.                                         SInt16 verb, SInt16 colorsRequested,
  89.                                         SInt16 colorPickMethod, SInt16 version );
  90. static void            SizeScrollBars ( WindowRef theWindow );
  91. static Point        GetMaximumWindowSize ( WindowRef theWindow );
  92.  
  93.  
  94.  
  95. // Default RGB Colors
  96.  
  97. static const RGBColor     kRGBBlack = {0x0000, 0x0000, 0x0000};
  98. static const RGBColor    kRGBWhite = {0xFFFF, 0xFFFF, 0xFFFF};
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105. //
  106. // This is called to create the application's window.
  107. //
  108. void CreateWindow ( void )
  109. {
  110.     OSErr        theErr;
  111.     WindowRef    theWindow;
  112.     
  113.     theErr = CreateDocumentWindow ( &theWindow );
  114.     if ( theErr )
  115.         AlertUser ( kGenericErrorStr, theErr, "\p" );
  116.     
  117.     return;
  118. }
  119.  
  120.  
  121.  
  122. //
  123. // This will close the application's window, dispose of any storage we've hung
  124. // off the window, and then dispose of the window itself.
  125. //
  126. WindowRef DestroyWindow ( WindowRef windowRef )
  127. {
  128.     if ( windowRef )
  129.     {
  130.         tWindowInfoPtr    theInfo;
  131.         
  132.         theInfo = (tWindowInfoPtr) GetWRefCon ( windowRef );
  133.         if ( theInfo )
  134.         {
  135.             if ( theInfo->hScrollBar )
  136.                 DisposeControl ( theInfo->hScrollBar );
  137.             if ( theInfo->vScrollBar )
  138.                 DisposeControl ( theInfo->vScrollBar );
  139.                 
  140.             if ( theInfo->offscreen )
  141.                 DisposeGWorld ( theInfo->offscreen );                
  142.             
  143.             DisposePtr ( (Ptr) theInfo );
  144.         }
  145.         
  146.         DisposeWindow ( windowRef );
  147.         
  148.     }
  149.     
  150.     return nil;
  151. }
  152.  
  153.  
  154.  
  155. void DoActivate ( EventRecord* theEvent )
  156. {
  157.     Boolean            bActiveFlag = theEvent->modifiers & resumeFlag;
  158.     WindowRef        theWindow = (WindowRef) theEvent->message;
  159.     GrafPtr            savePort;
  160.     tWindowInfoPtr    theInfo;
  161.     
  162.     
  163.     gInBackground = (theEvent->modifiers & resumeFlag) == 0;
  164.     
  165.     GetPort ( &savePort );
  166.     SetPortWindowPort ( theWindow );
  167.     
  168.     theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
  169.     
  170.     if ( bActiveFlag )
  171.     {
  172.         ShowControl ( theInfo->hScrollBar );
  173.         ShowControl ( theInfo->vScrollBar );
  174.     }
  175.     else
  176.     {
  177.         HideControl ( theInfo->hScrollBar );
  178.         HideControl ( theInfo->vScrollBar );
  179.         DrawClippedScrollBarLines ( theWindow );
  180.     }
  181.     
  182.     DrawClippedGrowIcon ( theWindow );
  183.     
  184.     SetPort ( savePort );
  185.     
  186.     return;
  187. }
  188.  
  189.  
  190.  
  191. void DoUpdate ( WindowRef theWindow )
  192. {
  193.     GrafPtr            savePort;
  194.     CGrafPtr        thePort;
  195.     
  196.     
  197.     thePort = GetWindowPort ( theWindow );
  198.     
  199.     GetPort ( &savePort );
  200.     SetPortWindowPort ( theWindow );
  201.     BeginUpdate ( theWindow );                    // visRgn temporarily = updateRgn
  202.     EraseRect ( &thePort->portRect );
  203.     
  204.     UpdateWindowContent ( theWindow );
  205.     
  206.     if ( gInBackground )
  207.         DrawClippedScrollBarLines ( theWindow );
  208.     else
  209.         UpdateControls ( theWindow, theWindow->visRgn );
  210.     DrawClippedGrowIcon ( theWindow );
  211.     
  212.     EndUpdate ( theWindow );                    // restore normal visRgn of grafport
  213.     SetPort ( savePort );
  214.     
  215.     return;
  216. }
  217.  
  218.  
  219.  
  220. void UpdateWindowContent ( WindowRef theWindow )
  221. {
  222.     tWindowInfoPtr    theInfo;
  223.     
  224.     theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
  225.     DrawOffscreenToWindow ( theInfo->offscreen, theWindow );
  226.     
  227.     return;
  228. }
  229.  
  230.  
  231.  
  232. void DoContentClick ( WindowRef theWindow, EventRecord* theEvent )
  233. {
  234.     OSErr        theErr = noErr;
  235.     WindowRef    frontWindow;
  236.     
  237.     // If a movable modal is active, ignore click in an inactive 
  238.     // window, otherwise select it or handle the content click.
  239.     
  240.     frontWindow = FrontWindow ( );
  241.     if ( theWindow != frontWindow )
  242.     {
  243.         if ( IsMovableModal ( frontWindow ) )
  244.             SysBeep ( 30 );
  245.         else
  246.             SelectWindow ( theWindow );
  247.     }
  248.     else
  249.     {
  250.         SInt16            thePart;
  251.         GrafPtr            savePort;
  252.         ControlRef        theControl;
  253.         Point            localPt;
  254.     
  255.         localPt = theEvent->where;
  256.         GlobalToLocal ( &localPt );
  257.         thePart = FindControl ( localPt, theWindow, &theControl );
  258.         
  259.         GetPort ( &savePort );
  260.         SetPortWindowPort ( theWindow );
  261.         
  262.         if ( thePart )
  263.         {
  264.             switch ( thePart )
  265.             {
  266.                 case inUpButton:
  267.                 case inDownButton:
  268.                 case inPageUp:
  269.                 case inPageDown:
  270.                     TrackControl ( theControl, localPt, gScrollControlActionUPP );
  271.                 break;
  272.                 
  273.                 case inThumb:
  274.                     if ( BeginThumbTracking ( theControl ) == noErr )
  275.                     {
  276.                         TrackControl ( theControl, localPt,
  277.                                         (ControlActionUPP) gScrollThumbActionUPP );
  278.                         EndThumbTracking ( );
  279.                     }
  280.                 break;
  281.             }
  282.         }
  283.         else
  284.             HandleContentClick ( theWindow, theEvent );
  285.             
  286.         SetPort ( savePort );
  287.     }
  288.         
  289.     return;
  290.     
  291. } // DoContentClick
  292.  
  293.  
  294.  
  295. void DoGrowWindow ( WindowRef theWindow, EventRecord* theEvent )
  296. {
  297.     WindowPtr            savePort;
  298.     SInt32                returnCoord;
  299.     Rect                resizeBounds;
  300.     SInt16                theWidth,
  301.                         theHeight;
  302.     Point                theMaxSize;
  303.     
  304.     GetPort ( &savePort );
  305.     theMaxSize = GetMaximumWindowSize ( theWindow );
  306.     SetRect ( &resizeBounds, 96, 96, theMaxSize.h, theMaxSize.v );
  307.     returnCoord = GrowWindow ( theWindow, theEvent->where, &resizeBounds );
  308.     theHeight   = HiWord ( returnCoord );
  309.     theWidth = LoWord ( returnCoord );
  310.     
  311.     SizeWindow ( theWindow, theWidth, theHeight, true );
  312.     SizeScrollBars ( theWindow );
  313.     SetPort ( theWindow );
  314.     InvalRect ( &theWindow->portRect );
  315.     
  316.     SetPort ( savePort );
  317.     
  318.     
  319.     return;
  320. }
  321.  
  322.  
  323.  
  324. void DoDragWindow ( WindowRef theWindow, EventRecord* theEvent )
  325. {
  326.     WindowRef    frontWindow;
  327.     
  328.     
  329.     // If a movable modal is active, ignore click in an inactive 
  330.     // title bar, otherwise let the Window Manager handle it.
  331.     
  332.     frontWindow = FrontWindow ( );
  333.     if ( theWindow != frontWindow && IsMovableModal ( frontWindow ) )
  334.         SysBeep ( 30 );
  335.     else                                
  336.     {
  337.         RgnHandle    theRgn;
  338.         Rect        dragRect;
  339.         
  340.         theRgn = GetGrayRgn ( );
  341.         dragRect = (*theRgn)->rgnBBox;
  342.         DragWindow ( theWindow, theEvent->where, &dragRect );
  343.     }
  344.     
  345.     return;
  346. }
  347.  
  348.  
  349.  
  350. OSErr DoAboutBox ( void )
  351. {
  352.  
  353.     OSErr            theErr = noErr;
  354.     SInt16            theItem = 0;
  355.     GrafPtr            savePort = nil;
  356.     DialogRef        theDialog;
  357.     ModalFilterUPP    theFilter = nil;
  358.     
  359.     
  360.     theDialog = GetNewDialog ( kAboutDialog, nil, (WindowPtr) -1 );
  361.     
  362.     GetPort ( &savePort );
  363.     SetPort ( theDialog );
  364.  
  365.     ShowWindow ( theDialog );
  366.     
  367.     // Get the standard filter proc
  368.     theErr = GetStdFilterProc ( &theFilter );
  369.     if ( theErr )
  370.         goto CleanupAndBail;
  371.     
  372.     // Tell the dialog manager to use the default button
  373.     SetDialogDefaultItem ( theDialog, kStdOkItemIndex );
  374.       
  375.       
  376.     // Modal dialog loop    
  377.     do
  378.     {
  379.         // Use "theFilter" in ModalDialog call
  380.            ModalDialog ( theFilter, &theItem );
  381.            
  382.     } while ( theItem != kStdOkItemIndex );
  383.     
  384.     
  385. CleanupAndBail:
  386.     
  387.     DisposeDialog ( theDialog );
  388.     SetPort ( savePort );
  389.  
  390.     return theErr;
  391. }
  392.  
  393.  
  394.  
  395. //
  396. // Creates a document window containing a picture.
  397. //
  398. static OSErr CreateDocumentWindow ( WindowRef* windowRef )
  399. {
  400.     OSErr            theErr = noErr;
  401.     WindowRef        theWindow;
  402.     Point            theImageSize;
  403.     PicHandle        thePict = nil;
  404.     PictInfo        thePictInfo;
  405.     tWindowInfoPtr    theInfo;
  406.     
  407.     
  408.     
  409.     theWindow = GetNewCWindow ( kDisplayWindow, nil, (WindowRef) -1 );
  410.     if ( theWindow == nil )
  411.         return (ResError ( )) ? ResError ( ) : resNotFound;
  412.     
  413.     theErr = CreateWindowInfo ( theWindow, sizeof ( tWindowInfo ) );
  414.     if ( theErr )    goto CleanupAndBail;
  415.     
  416.     theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
  417.     
  418.     SetPortWindowPort ( theWindow );
  419.     
  420.     thePict = GetPicture ( kPictureID );
  421.     if ( thePict == nil )    goto CleanupAndBail;
  422.     
  423.     theErr = SafeGetPictInfo ( thePict, &thePictInfo, returnColorTable, 256, systemMethod, 0 );
  424.     if ( theErr )    goto CleanupAndBail;
  425.     
  426.     theImageSize.h = thePictInfo.sourceRect.right - thePictInfo.sourceRect.left;
  427.     theImageSize.v = thePictInfo.sourceRect.bottom - thePictInfo.sourceRect.top;
  428.     
  429.     theInfo->offscreen = CreateOffscreen ( (thePictInfo.depth <= 8) ? thePictInfo.theColorTable : nil,
  430.                                             theImageSize.h, theImageSize.v, thePictInfo.depth,
  431.                                             kNoFlags );
  432.     if ( theInfo->offscreen == nil )    goto CleanupAndBail;
  433.     
  434.     theInfo->hScrollBar = GetNewControl ( kScrollBar, theWindow );
  435.     theInfo->vScrollBar = GetNewControl ( kScrollBar, theWindow );
  436.     if ( theInfo->hScrollBar == nil || theInfo->vScrollBar == nil)
  437.         goto CleanupAndBail;
  438.     
  439.     
  440.     // Setup the correct control values
  441.     SetControlMinimum ( theInfo->hScrollBar, 0 );
  442.     SetControlMinimum ( theInfo->vScrollBar, 0 );
  443.     SetControlValue ( theInfo->hScrollBar, 0 );
  444.     SetControlValue ( theInfo->vScrollBar, 0 );
  445.     
  446.     SizeScrollBars ( theWindow );
  447.     
  448.     theErr = DrawPictToOffscreen ( thePict, theInfo->offscreen );
  449.     if ( theErr )    goto CleanupAndBail;
  450.     
  451.     SelectWindow ( theWindow );
  452.     ShowWindow ( theWindow );
  453.     
  454.     *windowRef = theWindow;
  455.     
  456.     if ( thePict )
  457.         ReleaseResource ( (Handle) thePict );
  458.         
  459.     return noErr;
  460.     
  461. CleanupAndBail:
  462.     
  463.     // Don't forget to free any storage we've used so far
  464.     if ( thePict )
  465.         ReleaseResource ( (Handle) thePict );
  466.     
  467.     DestroyWindow ( theWindow );
  468.     
  469.     return theErr;
  470. }
  471.  
  472.  
  473.  
  474. static GWorldPtr CreateOffscreen ( CTabHandle theCTabHndl, SInt16 theXsize, SInt16 theYsize,
  475.                                     SInt16 theBitDepth, GWorldFlags theFlags )
  476. {
  477.     GWorldPtr    theGWorld = nil;
  478.     QDErr        theErr;
  479.     Rect        theRect;
  480.     
  481.     
  482.     SetRect ( &theRect, 0, 0, theXsize, theYsize );
  483.     theErr = NewGWorld ( &theGWorld, theBitDepth, &theRect, theCTabHndl, nil, theFlags );
  484.     
  485.     #if WARNINGS
  486.     if ( theErr )
  487.         DebugStrNum ( "\p CreateOffscreen: ", theErr );
  488.     #endif
  489.     
  490.     return theGWorld;
  491. }
  492.  
  493.  
  494.  
  495. static OSErr DrawPictToOffscreen ( PicHandle thePictHndl, GWorldPtr theOffscreen )
  496. {
  497.     PixMapHandle    theGWorldPMHndl;
  498.     GDHandle        saveGDevice;
  499.     CGrafPtr        saveGWorld;
  500.     OSErr            theErr = noErr;
  501.     
  502.     
  503.     GetGWorld ( &saveGWorld, &saveGDevice );
  504.     SetGWorld ( theOffscreen, nil );
  505.     
  506.     // We'll initialize out port settings here.
  507.     // If you don't set the foreground and background colors to black
  508.     // and white, colorisation can occur during the call to CopyBits.
  509.     RGBForeColor ( &kRGBBlack );                            
  510.     RGBBackColor ( &kRGBWhite );
  511.     // Reset the transfer mode
  512.     PenMode ( srcCopy );                                    
  513.     
  514.     
  515.     theGWorldPMHndl = GetGWorldPixMap ( theOffscreen );
  516.     LockPixels ( theGWorldPMHndl );
  517.     
  518.     EraseRect ( &theOffscreen->portRect );
  519.     // render the image into the offscreen buffer
  520.     HLock ( (Handle) thePictHndl );
  521.     DrawPicture ( thePictHndl, &theOffscreen->portRect );
  522.     HUnlock ( (Handle) thePictHndl );
  523.     
  524.     UnlockPixels ( theGWorldPMHndl );
  525.     SetGWorld ( saveGWorld, saveGDevice );
  526.     
  527.     return    theErr;
  528. }
  529.  
  530.  
  531.  
  532. static OSErr DrawOffscreenToWindow ( GWorldPtr theOffscreen, WindowPtr theWindow )
  533. {
  534.     OSErr            theErr = noErr;
  535.     CGrafPtr        savePort = nil;
  536.     GDHandle        saveGDevice;
  537.     PixMapHandle    thePixMapHndl = nil;
  538.     RGBColor        saveForeColor,
  539.                     saveBackColor;
  540.     Rect            sourceRect,
  541.                     destRect;
  542.     
  543.     
  544.     GetGWorld ( &savePort, &saveGDevice );
  545.     SetGWorld ( theOffscreen, nil );
  546.     GetForeColor ( &saveForeColor );
  547.     GetBackColor ( &saveBackColor );
  548.     
  549.     RGBForeColor ( &kRGBBlack );
  550.     RGBBackColor ( &kRGBWhite );
  551.     thePixMapHndl = GetGWorldPixMap ( theOffscreen );
  552.     if ( PixMap32Bit ( thePixMapHndl ) )                    // if 32bit mode needed == true
  553.         SaveSetMMUMode ( true );
  554.     if ( !LockPixels ( thePixMapHndl ) )
  555.         goto CleanupAndBail;
  556.         
  557.     sourceRect = theOffscreen->portRect;
  558.     destRect = theWindow->portRect;
  559.     destRect.right -= kScrollBarWidth;                        // exclude scrollbar area
  560.     destRect.bottom -= kScrollBarWidth;
  561.     if ( !EqualRect ( &sourceRect, &destRect ) )
  562.         sourceRect = GetWindowVisibleRect ( theWindow, destRect.right, destRect.bottom );
  563.     SetGWorld ( savePort, saveGDevice );
  564.     savePort = nil;
  565.     
  566.     CopyBits ( (BitMap*) *thePixMapHndl, (BitMap*) &theWindow->portBits,
  567.                     &sourceRect, &destRect, srcCopy, nil);
  568.     
  569.     
  570. CleanupAndBail:
  571.     
  572.     if ( savePort )
  573.         SetGWorld ( savePort, saveGDevice );
  574.     
  575.     RGBForeColor ( &saveForeColor );
  576.     RGBBackColor ( &saveBackColor );
  577.     UnlockPixels ( thePixMapHndl );
  578.     SaveSetMMUMode ( false );
  579.     
  580.     return theErr;
  581. }
  582.  
  583.  
  584.  
  585. static void DrawClippedScrollBarLines ( WindowRef theWindow )
  586. {
  587.     CGrafPtr    thePort;
  588.     Rect        theRect;
  589.     
  590.     
  591.     thePort = GetWindowPort ( theWindow );
  592.     theRect = thePort->portRect;
  593.     
  594.     MoveTo ( theRect.left, theRect.bottom - kScrollBarWidthAdjust );
  595.     LineTo ( theRect.right - kScrollBarWidthAdjust, theRect.bottom - kScrollBarWidthAdjust );
  596.     MoveTo ( theRect.right - kScrollBarWidthAdjust, theRect.top );
  597.     LineTo ( theRect.right - kScrollBarWidthAdjust, theRect.bottom - kScrollBarWidthAdjust );
  598.     
  599.     return;
  600. }
  601.  
  602.  
  603.  
  604. static void DrawClippedGrowIcon ( WindowRef theWindow )
  605. {
  606.     CGrafPtr    thePort;
  607.     RgnHandle    saveClip = nil;
  608.     Rect        newClip;
  609.     
  610.     
  611.     thePort = GetWindowPort ( theWindow );
  612.     saveClip = NewRgn ( );
  613.     GetClip ( saveClip );
  614.     
  615.     newClip = thePort->portRect;
  616.     newClip.top = newClip.bottom - kScrollBarWidth;
  617.     newClip.left = newClip.right - kScrollBarWidth;
  618.     ClipRect ( &newClip );
  619.     DrawGrowIcon ( theWindow );
  620.     
  621.     SetClip ( saveClip );
  622.     DisposeRgn ( saveClip );
  623.     
  624.     return;
  625. }
  626.  
  627.  
  628.  
  629. static Rect GetWindowVisibleRect ( WindowRef theWindow, SInt16 theSizeX, SInt16 theSizeY )
  630. {
  631.     Rect            displayRect;
  632.     SInt16            theValueX,
  633.                     theValueY;
  634.     tWindowInfoPtr    theInfo;
  635.     
  636.     theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
  637.     theValueX = GetControlValue ( theInfo->hScrollBar );
  638.     theValueY = GetControlValue ( theInfo->vScrollBar );
  639.     SetRect ( &displayRect, theValueX, theValueY, theValueX + theSizeX, theValueY + theSizeY );
  640.     
  641.     return displayRect;
  642. }
  643.  
  644.  
  645.  
  646. static void    SaveSetMMUMode ( Boolean bIsSaveMode )
  647. {
  648.     static signed char        theAddrMode = true32b;
  649.     static Boolean            bSwapModeNeeded = false;
  650.     
  651.     if ( bIsSaveMode )
  652.     {
  653.         if ( GetMMUMode ( ) == false32b )            // get current addr mode
  654.         {
  655.             bSwapModeNeeded = true;                    // in 24 bit mode swap needed
  656.             SwapMMUMode ( &theAddrMode );            // switch to 32 bit mode
  657.         }
  658.     }
  659.     else if ( bSwapModeNeeded )
  660.         SwapMMUMode ( &theAddrMode );
  661.         
  662.     return;
  663. }
  664.  
  665.  
  666.  
  667. static void HandleContentClick ( WindowRef theWindow, EventRecord* event )
  668. {
  669.     Point        localPt;
  670.     
  671.     localPt = event->where;
  672.     GlobalToLocal ( &localPt );
  673.     
  674.     // Handle any content clicks here
  675.     
  676.     return;
  677. }
  678.  
  679.  
  680.  
  681. //
  682. // Creates the storage for the data to hang off a window or dialog
  683. //
  684. static OSErr CreateWindowInfo ( WindowRef windowRef, Size infoSize )
  685. {
  686.     OSErr    theErr;
  687.     Ptr        theInfo = nil;
  688.     
  689.     
  690.     theInfo = NewPtrClear ( infoSize );
  691.     theErr = MemError ( );
  692.     if ( theErr )
  693.         return theErr;
  694.     
  695.     SetWRefCon ( windowRef, (long) theInfo );
  696.     
  697.     return noErr;
  698. }
  699.  
  700.  
  701.  
  702. //
  703. // The GetPictInfo routine has a bug which will allow all hell to
  704. // break loose if there isn't enough temporary memory available.
  705. //
  706. static pascal OSErr SafeGetPictInfo ( PicHandle thePictHandle, PictInfo* thePictInfo, SInt16 verb, SInt16 colorsRequested, SInt16 colorPickMethod, SInt16 version )
  707. {
  708.     const SInt32 kMinLowMem    = 10240;        // 10K isn't too much to ask for!
  709.     
  710.     if ( TempFreeMem ( )  < kMinLowMem )
  711.         return memFullErr;
  712.     
  713.     return GetPictInfo ( thePictHandle, thePictInfo, verb, colorsRequested, colorPickMethod, version );
  714. }
  715.  
  716.  
  717.  
  718. static void SizeScrollBars ( WindowRef theWindow )
  719. {
  720.     SInt16            maxXsize,
  721.                     maxYsize;
  722.     tWindowInfoPtr    theInfo;
  723.     
  724.     
  725.     theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
  726.     
  727.     MoveControl ( theInfo->vScrollBar, theWindow->portRect.right - kScrollBarWidthAdjust,
  728.                                         theWindow->portRect.top - 1 );
  729.     MoveControl ( theInfo->hScrollBar, theWindow->portRect.left - 1, 
  730.                                         theWindow->portRect.bottom - kScrollBarWidthAdjust );
  731.     SizeControl ( theInfo->vScrollBar, kScrollBarWidth,
  732.                                         theWindow->portRect.bottom - theWindow->portRect.top - 13 );
  733.     SizeControl ( theInfo->hScrollBar, theWindow->portRect.right - theWindow->portRect.left - 13,
  734.                                         kScrollBarWidth );
  735.                                         
  736.     maxXsize = theInfo->offscreen->portRect.right - 
  737.                 ((theWindow->portRect.right - kScrollBarWidthAdjust) - theWindow->portRect.left);
  738.     maxYsize = theInfo->offscreen->portRect.bottom - 
  739.                 ((theWindow->portRect.bottom - kScrollBarWidthAdjust) - theWindow->portRect.top);
  740.     SetControlMaximum ( theInfo->vScrollBar, maxYsize );
  741.     SetControlMaximum ( theInfo->hScrollBar, maxXsize );
  742.     
  743.     return;
  744. }
  745.  
  746.  
  747.  
  748. //
  749. // Calculates the maximum window size based on the image size and the
  750. // current size of the main screen. The image size is used, but resticted
  751. // by the current screen size.
  752. //
  753. static Point GetMaximumWindowSize ( WindowRef theWindow )
  754. {
  755.     GDHandle            theMainGDevHndl;
  756.     Point                theWindowSize,
  757.                         theImageSize;
  758.     tWindowInfoPtr        theInfo;
  759.     
  760.     
  761.     theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
  762.     
  763.     // Calulate the image size
  764.     theImageSize.h = theInfo->offscreen->portRect.right - theInfo->offscreen->portRect.left;
  765.     theImageSize.v = theInfo->offscreen->portRect.bottom - theInfo->offscreen->portRect.top;
  766.     theImageSize.h += kScrollBarWidth;
  767.     theImageSize.v += kScrollBarWidth;
  768.     
  769.     // Calulate the screen size
  770.     theMainGDevHndl = GetMainDevice ( );
  771.     theWindowSize.h = (*theMainGDevHndl)->gdRect.right - (*theMainGDevHndl)->gdRect.left;
  772.     theWindowSize.v = (*theMainGDevHndl)->gdRect.bottom - (*theMainGDevHndl)->gdRect.top;
  773.     theWindowSize.v -= GetMBarHeight ( );
  774.     
  775.     // Make sure the image size is within the constraints of the screen
  776.     theWindowSize.h = theWindowSize.h < theImageSize.h ? theWindowSize.h : theImageSize.h;
  777.     theWindowSize.v = theWindowSize.v < theImageSize.v ? theWindowSize.v : theImageSize.v;
  778.     
  779.     return theWindowSize;
  780. }
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.